#include "vec4.h"

vec4::vec4()
:x(0),y(0),z(0),w(0)
{
}

vec4::vec4(float x_,float y_,float z_,float w_ = 1)
:x(x_),y(y_),z(z_),w(1)
{
}

vec4::vec4(float value)
:x(value),y(value),z(value),w(value)
{
}

vec4::vec4(const vec4 &copy)
:x(copy.x),y(copy.x),z(copy.x),w(copy.w)
{
}

vec4::vec4(const vec3& v, float w_)
:x(v.x),y(v.y),z(v.z),w(w_)
{
}

inline vec4& vec4::operator =(const vec4 &other)
{
	x = other.x;
	y = other.y;
	z = other.z;
	w = other.w;

	return *this;
}

inline bool vec4::operator == (const vec4 &other) const
{
	return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w);
}

inline bool vec4::operator != (const vec4 &other) const
{
	return (x != other.x) || (y != other.y) || (z != other.z)|| (w != other.w);
}

inline vec4 vec4::operator +(const vec4 &other) const
{
	return vec4(x + other.x, y + other.y, z + other.z, w + other.w);
}

inline vec4 vec4::operator +(float value) const
{
	return vec4(x + value, y + value, z + value, w + value);
}

inline vec4 vec4::operator *(const vec4 &other) const
{
	return vec4(x * other.x, y * other.y, z * other.z, w * other.w);
}

inline vec4 vec4::operator *(float value) const
{
	return vec4(x * value, y * value, z * value, w * value);
}


inline vec4& vec4::operator +=(const vec4 &other)
{
#ifdef SIGEL_USE_SSE

	/*
	float *a = &x;
	float *b = (float *)(&other.x);

	__asm
	{
		movaps xmm0,a
		movaps xmm1,b
		addps xmm0,xmm1
		movaps a,xmm0
	}
	*/


	x+=other.x;
	y+=other.y;
	z+=other.z;
	w+=other.w;
#else
	x+=other.x;
	y+=other.y;
	z+=other.z;
	w+=other.w;
#endif


	return *this;
}

inline vec4& vec4::operator +=(float value)
{
	x+=value;
	y+=value;
	z+=value;
	w+=value;

	return *this;
}

inline vec4& vec4::operator *=(const vec4 &other)
{
	x*=other.x;
	y*=other.y;
	z*=other.z;
	w*=other.w;

	return *this;
}

inline vec4& vec4::operator *=(float value)
{
	x*=value;
	y*=value;
	z*=value;
	w*=value;

	return *this;
}


inline vec4 vec4::operator -(const vec4 &other) const
{
	return vec4(x - other.x, y - other.y, z - other.z, w - other.w);
}

inline vec4 vec4::operator -(float value) const
{
	return vec4(x - value, y - value, z - value, w - value);
}

inline vec4 vec4::operator /(const vec4 &other) const
{
	return vec4(x / other.x, y / other.y, z / other.z, w / other.w);
}

inline vec4 vec4::operator /(float value) const
{
	return vec4(x / value, y / value, z / value, w / value);
}


inline vec4& vec4::operator -=(const vec4 &other)
{
	x -= other.x;
	y -= other.y;
	z -= other.z;
	w -= other.w;

	return *this;
}

inline vec4& vec4::operator -=(float value)
{
	x -= value;
	y -= value;
	z -= value;
	w -= value;

	return *this;
}

inline vec4& vec4::operator /=(const vec4 &other)
{
	x /= other.x;
	y /= other.y;
	z /= other.z;
	w /= other.w;

	return *this;
}

inline vec4& vec4::operator /=(float value)
{
	x /= value;
	y /= value;
	z /= value;
	w /= value;

	return *this;
}

inline vec4 vec4::operator +() const
{
	return vec4(x,y,z,w);
}

inline vec4 vec4::operator -() const
{
	return vec4(-x,-y,-z,-w);
}



inline vec4::operator float*()
{
	return &x;
}

inline vec4::operator const float*() const
{
	return &x;
}

inline float vec4::operator [] (int index)
{
	return *(&x + index);
}


inline float vec4::len()
{
	return sqrt(x*x + y*y + z*z + w*w);
}

inline void vec4::normalize()
{
	float l = len();
	x /= l;
	y /= l;
	z /= l;
	w /= l;
}

inline void vec4::normize()
{
	x /= w;
	y /= w;
	z /= w;
	w = 1;
}

inline vec4 vec4::lerp(const vec4 &other, float scalar) const
{
	return vec4(x + (other.x - x) * scalar
		,y + (other.y - y) * scalar
		,z + (other.z - z) * scalar
		,w + (other.w - w) * scalar);
}

inline void vec4::lerpme(const vec4 &other, float scalar)
{
	x += (other.x - x) * scalar;
	y += (other.y - y) * scalar;
	z += (other.z - z) * scalar;
	w += (other.w - w) * scalar;
}
